/**
 * Created by Ivan Babanin (22.07.2007 20:16:58)
 * This part of code is strictly confidential.
 * © Magnificent Software Inc.
 */
package com.silverhaze.diamond.client.ui.frame;

import com.silverhaze.commons.db.datasource.ObjectEntity;
import com.silverhaze.diamond.common.entity.SystemUser;
import com.silverhaze.diamond.client.data.dao.DAOLocator;
import com.silverhaze.diamond.client.ui.UIHelper;
import com.silverhaze.diamond.client.ui.UIStringConstants;
import com.silverhaze.diamond.client.ui.dialogs.Dialogs;
import com.silverhaze.diamond.client.ui.table.model.UsersTableModel;
import com.silverhaze.diamond.client.utils.db.ServiceDataSource;
import com.silverhaze.commons.utils.crypt.MD5;

import javax.swing.*;
import javax.swing.border.TitledBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Date;
import java.util.List;

/**
 * Author: Ivan Babanin
 * © Lizard Software, 2008 y.
 */
public class UsersFrame extends AbstractFrame {
    private static UsersFrame usersFrame;

    private JTable usersTable;
    private UsersTableModel usersModel;

    private JPanel addPanel;
    private JPanel editPanel;

    JButton deleteButton;
    JToggleButton editButton;
    JToggleButton createButton;

    // Add
    private JButton addCreateBtn;
    private JCheckBox addLevelBox;
    private JTextField addLoginField;
    private JTextField addPasswordField;

    // Edit
    private JButton editCreateBtn;
    private JCheckBox editLevelBox;
    private JLabel editLoginLabel;
    private JTextField editPasswordField;

    // Selected
    private SystemUser selectedUser;
    private int selectedIndex;

    public UsersFrame() {
        alignFrame();

        addWindowListener(new WindowAdapter() {
            public void windowGainedFocus(WindowEvent e) {
                usersModel.refreshModelAll();
            }
        });
    }

    protected void initializeSystem() {
        selectedUser = null;

        usersModel = new UsersTableModel(DAOLocator.getInstance().getUsers());

        usersTable = new JTable(usersModel);
        usersTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
            public void valueChanged(ListSelectionEvent e) {
                selectedIndex = usersTable.getSelectedRow();
                if (selectedIndex >= 0) {
                    selectedUser = usersModel.getObjectAtRow(selectedIndex);

                    // Enable components
                    if (!isEditPanelEnabled()) {
                        setEditPanelEnabled(true);
                    }
                    deleteButton.setEnabled(true);


                    if (selectedUser != null) {
                        editLoginLabel.setText(selectedUser.getLogin());
                        editPasswordField.setText("");
                        editLevelBox.setSelected(selectedUser.isAdmin());
                    }
                }
            }
        });
    }

    protected void init() {
        super.init();

        setTitle(UIHelper.getCaption() + " - " + UIStringConstants.USERS);

        add(initializeTablePanel(), BorderLayout.CENTER);
        add(initializeBottomPanel(), BorderLayout.PAGE_END);

        pack();
    }

    private JPanel initilizeAddPanel() {
        JPanel addPanel = new JPanel(new BorderLayout());
        addPanel.setBorder(new TitledBorder(" " + UIStringConstants.CREATE_USER + " "));

        addLoginField = new JTextField();
        addPasswordField = new JTextField();
        addLevelBox = new JCheckBox(UIStringConstants.ADMINISTRATOR);

        addCreateBtn = new JButton(UIStringConstants.CREATE);
        addCreateBtn.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                String login = addLoginField.getText().trim();
                String password = addPasswordField.getText().trim();

                if (!login.equals("") && !password.equals("")) {
                    if (!isLoginExists(login)) {
                        SystemUser u = new SystemUser();

                        u.setLogin(login);
                        u.setPassword(MD5.crypt(password));
                        u.setAdmin(addLevelBox.isSelected());
                        u.setLastLogin(new Date());

                        DAOLocator.getInstance().add(u);

                        usersModel.refreshModelAll();

                        addLoginField.setText("");
                        addPasswordField.setText("");
                        addLevelBox.setSelected(false);
                    } else {
                        Dialogs.showErrorDialog(null, UIStringConstants.DUPLICATE_LOGIN);
                    }
                } else {
                    if (password.equals("")) {
                        Dialogs.showErrorDialog(null, UIStringConstants.EMPTY_PASSWORD);
                    } else if (login.equals("")) {
                        Dialogs.showErrorDialog(null, UIStringConstants.EMPTY_LOGIN);
                    }
                }
            }
        });

        Box hBox = Box.createHorizontalBox();
        hBox.add(Box.createHorizontalStrut(6));
        hBox.add(new JLabel(UIStringConstants.USER + ": "));
        hBox.add(Box.createHorizontalStrut(3));
        hBox.add(addLoginField);
        hBox.add(Box.createHorizontalStrut(6));
        hBox.add(new JLabel(UIStringConstants.PASSWORD + ": "));
        hBox.add(Box.createHorizontalStrut(3));
        hBox.add(addPasswordField);
        hBox.add(Box.createHorizontalStrut(6));
        hBox.add(addLevelBox);
        hBox.add(Box.createHorizontalStrut(6));
        hBox.add(addCreateBtn);
        hBox.add(Box.createHorizontalStrut(6));

        Box vBox = Box.createVerticalBox();
        vBox.add(Box.createVerticalStrut(5));
        vBox.add(hBox);
        vBox.add(Box.createVerticalStrut(5));

        addPanel.add(vBox, BorderLayout.CENTER);

        return addPanel;
    }

    private boolean isLoginExists(String login) {
        List<ObjectEntity> users = DAOLocator.getInstance().getUsers();

        for (ObjectEntity e : users) {
            SystemUser user = (SystemUser) e;

            if (login.equals(user.getLogin())) {
                return true;
            }
        }

        return false;
    }

    private void setEditPanelEnabled(boolean enable) {
        editLoginLabel.setEnabled(enable);
        editPasswordField.setEnabled(enable);
        editLevelBox.setEnabled(enable);
        editCreateBtn.setEnabled(enable);
    }

    private boolean isEditPanelEnabled() {
        return editLoginLabel.isEnabled() && editPasswordField.isEnabled() && editLevelBox.isEnabled();
    }

    private JPanel initilizeEditPanel() {
        JPanel editPanel = new JPanel(new BorderLayout());
        editPanel.setBorder(new TitledBorder(" " + UIStringConstants.EDIT_USER + " "));

        editLoginLabel = new JLabel();
        editPasswordField = new JTextField();
        editLevelBox = new JCheckBox(UIStringConstants.ADMINISTRATOR);
        editCreateBtn = new JButton(UIStringConstants.SAVE);

        editCreateBtn.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                String login = editLoginLabel.getText().trim();
                String password = editPasswordField.getText().trim();

                if (!login.equals("") && !password.equals("")) {
                    if (selectedUser.getId() != 1) {
                        selectedUser.setLogin(login);
                        selectedUser.setPassword(MD5.crypt(password));
                        selectedUser.setAdmin(editLevelBox.isSelected());

                        ServiceDataSource.getInstance().update(selectedUser);

                        usersModel.refreshModelAll();

                        editPasswordField.setText("");
                    } else {
                        Dialogs.showErrorDialog(null, "Вы не можете редактировать данного пользователя");
                    }
                } else {
                    if (password.equals("")) {
                        Dialogs.showErrorDialog(null, UIStringConstants.EMPTY_PASSWORD);
                    } else if (login.equals("")) {
                        Dialogs.showErrorDialog(null, UIStringConstants.ENTER_LOGIN);
                    }
                }
            }
        });

        Box hBox = Box.createHorizontalBox();
        hBox.add(Box.createHorizontalStrut(6));
        hBox.add(new JLabel(UIStringConstants.LOGIN + ": "));
        hBox.add(Box.createHorizontalStrut(3));
        hBox.add(editLoginLabel);
        hBox.add(Box.createHorizontalStrut(6));
        hBox.add(new JLabel(UIStringConstants.PASSWORD + ": "));
        hBox.add(Box.createHorizontalStrut(3));
        hBox.add(editPasswordField);
        hBox.add(Box.createHorizontalStrut(6));
        hBox.add(editLevelBox);
        hBox.add(Box.createHorizontalStrut(6));
        hBox.add(editCreateBtn);
        hBox.add(Box.createHorizontalStrut(6));

        Box vBox = Box.createVerticalBox();
        vBox.add(Box.createVerticalStrut(5));
        vBox.add(hBox);
        vBox.add(Box.createVerticalStrut(5));

        setEditPanelEnabled(false);

        editPanel.add(vBox, BorderLayout.CENTER);

        return editPanel;
    }

    private JPanel initializeBottomPanel() {
        JPanel panel = new JPanel(new BorderLayout());

        addPanel = initilizeAddPanel();
        editPanel = initilizeEditPanel();

        addPanel.setVisible(createButton.isSelected());
        editPanel.setVisible(editButton.isSelected());

        Box vBox = Box.createVerticalBox();
        vBox.add(Box.createVerticalStrut(5));
        vBox.add(addPanel);
        vBox.add(editPanel);

        panel.add(vBox, BorderLayout.CENTER);

        return panel;
    }

    private JPanel initializeTablePanel() {
        JPanel tablePanel = new JPanel(new BorderLayout());
        tablePanel.setBorder(new TitledBorder(" " + UIStringConstants.USERS + " "));

        usersTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
        tablePanel.add(new JScrollPane(usersTable), BorderLayout.CENTER);

        createButton = new JToggleButton(UIStringConstants.CREATE);
        createButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                addPanel.setVisible(createButton.isSelected());
            }
        });

        editButton = new JToggleButton(UIStringConstants.EDIT);
        editButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                editPanel.setVisible(editButton.isSelected());
            }
        });

        deleteButton = new JButton(UIStringConstants.DELETE);
        deleteButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (selectedUser != null) {
                    if (selectedUser.getId() != 1) {
                        DAOLocator.getInstance().remove(selectedUser);
                        selectedUser = null;
                    } else {
                        Dialogs.showErrorDialog(null, UIStringConstants.CANT_DELETE_USER);
                    }
                }
                deleteButton.setEnabled(false);
                usersModel.refreshModelAll();
            }
        });
        deleteButton.setEnabled(false);

        Box hBox = Box.createHorizontalBox();
        hBox.add(Box.createHorizontalGlue());
        hBox.add(createButton);
        hBox.add(Box.createHorizontalStrut(2));
        hBox.add(editButton);
        hBox.add(Box.createHorizontalStrut(2));
        hBox.add(deleteButton);

        Box vBox = Box.createVerticalBox();
        vBox.add(Box.createVerticalStrut(5));
        vBox.add(hBox);

        tablePanel.add(vBox, BorderLayout.PAGE_END);

        return tablePanel;
    }

    protected void createComponents() {

    }

    public static void showUsers() {
        if (usersFrame == null) {
            usersFrame = new UsersFrame();
        }

        usersFrame.setVisible(true);
    }
}

